package cn.jb698.codec.msm.generator.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.text.ParseException;
import java.util.Map;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

public class CodecVelocityUtils {


	/**
	 * 清理语法前的空字符(空格及tab字符)
	 * @param templateStr
	 * @return
	 */
	public static String cleanSpaceBeforeSchema(String templateStr ){
		
		String newTempStr = templateStr;
		if(newTempStr != null && newTempStr.length() > 1 ){
			newTempStr = newTempStr.replaceAll("((\\t{1,100}|[ ]{1,100})#if)", "#if");
			newTempStr = newTempStr.replaceAll("((\\t{1,100}|[ ]{1,100})#set)", "#set");
			newTempStr = newTempStr.replaceAll("((\\t{1,100}|[ ]{1,100})#end)", "#end");
			newTempStr = newTempStr.replaceAll("((\\t{1,100}|[ ]{1,100})#elseif)", "#elseif");
			newTempStr = newTempStr.replaceAll("((\\t{1,100}|[ ]{1,100})#else)", "#else");
			newTempStr = newTempStr.replaceAll("((\\t{1,100}|[ ]{1,100})#foreach)", "#foreach");
//			newTempStr = newTempStr.replaceAll("[)]\\r\\n", ")");
		}

		return newTempStr ;
	}

	/**
     * 从 输入流 读出 字节数组
     * @param inputStream
     * @param bufferSize 缓冲大小,默认 4096 
     * @return
     * @throws IOException
     */
    public static byte[] readByteArrayFromInputStream(InputStream inputStream , Integer bufferSize ) throws IOException {
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		if(bufferSize == null ){
			bufferSize = 2048;
		}
		byte[] buffer = new byte[bufferSize];
		int bytesRead = inputStream.read(buffer);
		while (bytesRead != -1) {
			byteArrayOutputStream.write(buffer, 0, bytesRead);
			bytesRead = inputStream.read(buffer);
		}
		return byteArrayOutputStream.toByteArray();
      }
    
	/**
	 * 根据模板创建代码
	 * 
	 * @param init_templateIs
	 *            初始化模板输入流
	 * @param content_templateIs
	 *            // 模板输入流
	 * @throws IOException
	 * @throws ParseException
	 */
	public static String parseVelocityTemplate(InputStream init_templateIs, InputStream content_templateIs) throws IOException, ParseException {
		String rtValue = null;
		if (content_templateIs == null) {
			return rtValue;
		}

		String init_templateStr = null; // 初始化的模板
		if (init_templateIs != null) {
			byte[] init_templateContentByteArray = readByteArrayFromInputStream(init_templateIs, 1024);
			init_templateStr = new String(init_templateContentByteArray);
			init_templateStr = cleanSpaceBeforeSchema(init_templateStr);
		}

		String templateContent = null; // 模板内容
		byte[] templateContentByteArray = readByteArrayFromInputStream(content_templateIs, 1024);
		templateContent = new String(templateContentByteArray);
		templateContent = cleanSpaceBeforeSchema(templateContent);

		if (init_templateStr != null) {
			rtValue = init_templateStr;
		}
		if (templateContent != null) {
			if (rtValue != null) {
				rtValue += templateContent;
			} else {
				rtValue = templateContent;
			}
		}

		return rtValue;
	}

	/**
	 * 默认引擎
	 */
	private static VelocityEngine defaultVe = new VelocityEngine(); 

	/**
	 * 解析为字符串
	 * @param tpltStr
	 * @param rootInfoMap
	 * @return
	 */
	public static String evaluateToStr(String tpltStr , Map<String,?> rootInfoMap ) {
		VelocityContext context = new VelocityContext(); // 创建Context 内容
		for(String key : rootInfoMap.keySet()){ 
			context.put(key, rootInfoMap.get(key));
		}
		return evaluateToStr(tpltStr,context);
	}

	/**
	 * 解析为字符串
	 * @param tpltStr
	 * @param rootInfoMap
	 * @return
	 */
	public static String evaluateToStr(String tpltStr , VelocityContext context) {
	    String rtStr = null ;
//		VelocityEngine velocityEngine = new VelocityEngine(); // 获取引擎
//	    VelocityContext context = new VelocityContext(); // 创建Context 内容
//	    for(String key : rootInfoMap.keySet()){ 
//	        context.put(key, rootInfoMap.get(key));
//	    }
	    Writer writer =  new StringWriter();
	    defaultVe.evaluate(context, writer, "", tpltStr); 
	    rtStr = writer.toString();
	    try {
	        writer.flush() ;
	    } catch (IOException e) {
	        throw new RuntimeException(e);
	    }
	    return rtStr ;
	}

	public static VelocityEngine getDefaultVe() {
		return defaultVe;
	}

	public static void setDefaultVe(VelocityEngine defaultVe) {
		CodecVelocityUtils.defaultVe = defaultVe;
	}
	
//	public static void main(String[] args) {
//	    String tpltStr = "     * 根据主键删除一条数据  \r\n#if( $pkColumnsLength > 0  ) #set( $tmpIndex = 0 ) #foreach($pkColumn in $pkColumns) #set( $tmpIndex = $tmpIndex + 1 )\r\n XXaabbcc";
//        String rstStr = cleanSpaceBeforeSchema(tpltStr);
//        System.err.println(rstStr);
//    }
	
}
